#!/usr/bin/env node

const http = require('http');
const fs = require('fs');
const path = require('path');
const child_process = require('child_process');
const https = require('https');

/**
 * Web配置服务器 - 提供基于Web界面的API密钥配置功能
 */
class WebConfigServer {
    constructor(projectRoot) {
        this.projectRoot = projectRoot;
        this.port = null; // 延迟到start方法中初始化
        this.server = null;
        this.isShuttingDown = false;
    }

    /**
     * 查找可用端口（支持优雅退出）
     * @param {number} startPort - 起始端口
     * @param {number} endPort - 结束端口
     * @returns {Promise<number>} - 可用端口
     */
    async findAvailablePort(startPort, endPort) {
        for (let port = startPort; port <= endPort; port++) {
            try {
                // 检查端口是否被占用，如果是则尝试优雅退出
                const isOccupiedAndShutdown = await this.checkAndShutdownExistingServer(port);
                if (isOccupiedAndShutdown) {
                    // 等待服务器完全退出
                    await this.waitForServerShutdown(port);
                }

                // 尝试绑定端口
                const isAvailable = await this.testPortAvailability(port);
                if (isAvailable) {
                    return port;
                }
            } catch (e) {
                // 端口检测失败，继续寻找下一个端口
            }
        }
        return startPort; // 如果都不可用，返回起始端口
    }

    /**
     * 检查端口是否被现有Web配置服务器占用，如果是则发送退出指令
     * @param {number} port - 要检查的端口
     * @returns {Promise<boolean>} - true表示有服务器被要求退出
     */
    async checkAndShutdownExistingServer(port) {
        return new Promise((resolve) => {
            const http = require('http');

            const options = {
                hostname: '127.0.0.1',
                port: port,
                path: '/shutdown',
                method: 'POST',
                timeout: 5000,
                headers: {
                    'Content-Type': 'application/json',
                    'User-Agent': 'Vision-Analyzer-Web-Config'
                }
            };

            const req = http.request(options, (res) => {
                let data = '';
                res.on('data', (chunk) => {
                    data += chunk;
                });
                res.on('end', () => {
                    if (res.statusCode === 200) {
                        const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                        if (!isTestEnvironment) {
                            console.log(`📤 已向端口 ${port} 发送优雅退出指令`);
                        }
                        resolve(true);
                    } else {
                        resolve(false);
                    }
                });
            });

            req.on('error', () => {
                // 端口可能不是我们的Web配置服务器，或者连接失败
                resolve(false);
            });

            req.on('timeout', () => {
                req.destroy();
                resolve(false);
            });

            // 发送退出指令
            req.write(JSON.stringify({
                action: 'shutdown',
                reason: 'new_instance_starting',
                message: '新的Web配置服务器实例正在启动，请优雅退出'
            }));

            req.end();
        });
    }

    /**
     * 等待服务器完全退出
     * @param {number} port - 端口号
     * @param {number} maxWait - 最大等待时间（毫秒）
     * @returns {Promise<void>}
     */
    async waitForServerShutdown(port, maxWait = 3000) {
        const startTime = Date.now();
        const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;

        while (Date.now() - startTime < maxWait) {
            const isStillOccupied = await this.testPortAvailability(port);
            if (isStillOccupied) {
                // 端口已经可用
                if (!isTestEnvironment) {
                    console.log(`✅ 端口 ${port} 已释放`);
                }
                return;
            }

            // 等待500ms后再检查
            await new Promise(resolve => setTimeout(resolve, 500));
        }

        if (!isTestEnvironment) {
            console.log(`⚠️ 等待端口 ${port} 释放超时`);
        }
    }

    /**
     * 测试端口是否可用
     * @param {number} port - 端口号
     * @returns {Promise<boolean>} - true表示端口可用
     */
    async testPortAvailability(port) {
        return new Promise((resolve) => {
            const http = require('http');
            const server = http.createServer();

            server.on('error', () => {
                resolve(false);
            });

            server.listen(port, '127.0.0.1', () => {
                server.close(() => {
                    resolve(true);
                });
            });
        });
    }

    /**
     * 启动Web配置服务器
     * @param {string} configDir - 配置目录（可选）
     * @param {Object} options - 启动选项
     * @returns {Promise<string>} - 服务器URL
     */
    async start(configDir = null, options = {}) {
        try {
            // 保存配置和选项
            this.configDir = configDir || this.projectRoot;
            this.options = options;

            // 确定端口
            if (options.port && typeof options.port === 'number') {
                this.port = options.port;
            } else {
                // 首先找到可用端口（可能需要优雅退出现有服务器）
                this.port = await this.findAvailablePort(37251, 37351);
            }

            return new Promise((resolve, reject) => {
                this.server = http.createServer((req, res) => {
                    this.handleRequest(req, res);
                });

                this.server.listen(this.port, '127.0.0.1', (err) => {
                    if (err) {
                        reject(err);
                    } else {
                        const url = `http://127.0.0.1:${this.port}`;
                        const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                        if (!isTestEnvironment) {
                            console.log(`🌐 Web配置服务器已启动: ${url}`);
                        }

                        // 自动打开浏览器（如果需要）
                        if (options.autoOpen !== false) {
                            const timer = setTimeout(() => {
                                this.openBrowser(url);
                            }, 1000);
                            // 在测试环境中不阻止进程退出
                            if (isTestEnvironment) {
                                timer.unref();
                            }
                        }

                        resolve(url);
                    }
                });

                this.server.on('error', async (err) => {
                    if (err.code === 'EADDRINUSE') {
                        const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                        if (!isTestEnvironment) {
                            console.log(`⚠️ 端口 ${this.port} 仍被占用，尝试下一个端口`);
                        }

                        // 如果指定了端口且被占用，寻找下一个可用端口
                        if (options.port && typeof options.port === 'number') {
                            try {
                                const newPort = await this.findAvailablePort(this.port + 1, this.port + 100);
                                this.port = newPort;

                                // 重新尝试启动服务器
                                this.server.listen(newPort, '127.0.0.1', (listenErr) => {
                                    if (listenErr) {
                                        reject(listenErr);
                                    } else {
                                        const url = `http://127.0.0.1:${newPort}`;
                                        const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                                        if (!isTestEnvironment) {
                                            console.log(`🌐 Web配置服务器已启动: ${url}`);
                                        }

                                        if (options.autoOpen !== false) {
                                            setTimeout(() => {
                                                this.openBrowser(url);
                                            }, 1000);
                                        }

                                        resolve(url);
                                    }
                                });
                            } catch (findErr) {
                                reject(err);
                            }
                        } else {
                            reject(err);
                        }
                    } else {
                        reject(err);
                    }
                });
            });
        } catch (error) {
            throw new Error(`启动Web配置服务器失败: ${error.message}`);
        }
    }

    /**
     * 停止服务器（优雅退出）
     */
    stop() {
        return new Promise((resolve) => {
            if (this.server && !this.isShuttingDown) {
                this.isShuttingDown = true;

                const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                if (!isTestEnvironment) {
                    console.log('🛑 正在优雅关闭Web配置服务器...');
                }

                // 设置关闭超时，进一步减少超时时间
                const shutdownTimeout = setTimeout(() => {
                    if (!isTestEnvironment) {
                        console.log('⏰ 服务器关闭超时，强制退出');
                    }
                    try {
                        if (this.server && this.server.listening) {
                            this.server.close();
                        }
                    } catch (error) {
                        if (!isTestEnvironment) {
                            console.warn('强制关闭服务器时出错:', error.message);
                        }
                    } finally {
                        this.server = null;
                        this.isShuttingDown = false;
                        resolve();
                    }
                }, 1000);

                this.server.close(() => {
                    clearTimeout(shutdownTimeout);
                    if (!isTestEnvironment) {
                        console.log('✅ Web配置服务器已优雅关闭');
                    }
                    // 立即清理引用
                    this.server = null;
                    this.isShuttingDown = false;
                    resolve();
                });
            } else {
                // 如果服务器已经在关闭或已关闭，直接返回
                this.server = null;
                this.isShuttingDown = false;
                resolve();
            }
        });
    }

    /**
     * 处理HTTP请求
     */
    handleRequest(req, res) {
        const url = new URL(req.url, `http://127.0.0.1:${this.port}`);

        // 设置CORS头
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
        res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

        if (req.method === 'OPTIONS') {
            res.writeHead(200);
            res.end();
            return;
        }

        if (req.method === 'GET' && url.pathname === '/') {
            this.serveConfigPage(res);
        } else if (req.method === 'GET' && url.pathname === '/manage') {
            this.serveManagePage(res);
        } else if (req.method === 'GET' && url.pathname === '/get-current-config') {
            this.handleGetCurrentConfig(req, res);
        } else if (req.method === 'POST' && url.pathname === '/shutdown') {
            this.handleShutdown(req, res);
        } else if (req.method === 'POST' && url.pathname === '/validate-provider') {
            this.handleProviderValidation(req, res);
        } else if (req.method === 'POST' && url.pathname === '/save-config') {
            this.handleSaveConfig(req, res);
        } else if (req.method === 'POST' && url.pathname === '/switch-provider') {
            this.handleSwitchProvider(req, res);
        } else if (req.method === 'POST' && url.pathname === '/delete-provider') {
            this.handleDeleteProvider(req, res);
        } else if (req.method === 'GET' && url.pathname === '/list-providers') {
            this.handleListProviders(req, res);
        } else if (req.method === 'POST' && url.pathname === '/add-model') {
            this.handleAddModel(req, res);
        } else if (req.method === 'POST' && url.pathname === '/delete-model') {
            this.handleDeleteModel(req, res);
        } else if (req.method === 'GET' && url.pathname === '/list-models') {
            this.handleListModels(req, res);
        } else if (req.method === 'POST' && url.pathname === '/switch-model') {
            this.handleSwitchModel(req, res);
        } else {
            res.writeHead(404);
            res.end('Not Found');
        }
    }

    /**
     * 处理获取当前配置请求
     */
    async handleGetCurrentConfig(req, res) {
        try {
            const existingConfig = this.loadExistingConfig();
            const currentProviderModel = existingConfig.currentProviderModel || 'unknown';

            // 解析当前provider和model
            let currentProvider = 'unknown';
            let currentModel = 'unknown';

            if (currentProviderModel !== 'unknown' && currentProviderModel !== '') {
                // 尝试解析provider-model格式
                const parts = currentProviderModel.split('-');
                if (parts.length >= 2) {
                    currentProvider = parts[0];
                    currentModel = parts.slice(1).join('-');
                } else {
                    // 如果不是provider-model格式，直接使用
                    currentProvider = 'unknown';
                    currentModel = currentProviderModel;
                }
            }

            const result = {
                success: true,
                current_provider: currentProvider,
                current_provider_model: currentProviderModel,
                config: existingConfig
            };

            res.setHeader('Content-Type', 'application/json');
            res.writeHead(200);
            res.end(JSON.stringify(result));
        } catch (error) {
            res.setHeader('Content-Type', 'application/json');
            res.writeHead(500);
            res.end(JSON.stringify({
                success: false,
                error: error.message
            }));
        }
    }

    /**
     * 处理优雅退出请求
     */
    async handleShutdown(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const isTestEnvironment = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined;
                    if (!isTestEnvironment) {
                        console.log('📡 收到优雅退出请求:', data);
                    }

                    // 返回确认响应
                    res.setHeader('Content-Type', 'application/json');
                    res.writeHead(200);
                    res.end(JSON.stringify({
                        success: true,
                        message: '服务器将在几秒内优雅退出',
                        timestamp: new Date().toISOString()
                    }));

                    // 延迟一点时间再退出，确保响应发送完成
                    setTimeout(async () => {
                        await this.stop();
                        // 在测试环境中不调用process.exit，让测试框架处理
                        const isTestEnvironment = process.env.NODE_ENV === 'test' ||
                                                 process.env.JEST_WORKER_ID !== undefined ||
                                                 typeof jest !== 'undefined';

                        if (!isTestEnvironment) {
                            // 给进程一点时间完全退出
                            setTimeout(() => {
                                process.exit(0);
                            }, 100);
                        }
                    }, 100);

                } catch (error) {
                    console.error('解析退出请求数据失败:', error);
                    res.writeHead(400);
                    res.end(JSON.stringify({
                        success: false,
                        error: 'Invalid request data'
                    }));
                }
            });

        } catch (error) {
            console.error('处理退出请求失败:', error);
            res.writeHead(500);
            res.end(JSON.stringify({
                success: false,
                error: 'Internal server error'
            }));
        }
    }

    /**
     * 提供配置页面
     */
    serveConfigPage(res) {
        const html = this.generateConfigPageHTML();
        res.setHeader('Content-Type', 'text/html; charset=utf-8');
        res.writeHead(200);
        res.end(html);
    }

    /**
     * 提供管理页面
     */
    serveManagePage(res) {
        const html = this.generateManagePageHTML();
        res.setHeader('Content-Type', 'text/html; charset=utf-8');
        res.writeHead(200);
        res.end(html);
    }

    /**
     * 读取现有配置（仅支持JSON格式）
     * @returns {Object} - 现有配置对象
     */
    loadExistingConfig() {
        const config = {
            currentProviderModel: '',
            moonshot: { apiKey: '', baseUrl: 'https://api.moonshot.cn/v1' },
            tencent: { apiKey: '', baseUrl: 'https://api.hunyuan.cloud.tencent.com/v1' },
            zai: { apiKey: '', baseUrl: 'https://open.bigmodel.cn/api/paas/v4' },
            custom: { name: '', apiKey: '', baseUrl: '' },
            providers: []
        };

        try {
            // 使用JSON配置管理器
            const JsonConfigManager = require('./lib/config/json-config-manager');
            const configManager = new JsonConfigManager(this.projectRoot);

            const jsonConfig = configManager.getConfig();
            if (jsonConfig && jsonConfig.providers) {
                // 将JSON配置转换为内部格式
                config.currentProviderModel = jsonConfig.current_provider_model || '';

                // 处理每个提供商
                for (const [providerKey, providerConfig] of Object.entries(jsonConfig.providers)) {
                    if (providerConfig.api_key) {
                        // 映射提供商名称
                        let internalName = providerKey;
                        if (providerKey === 'zai') internalName = 'zai';
                        else if (providerKey === 'moonshot') internalName = 'moonshot';
                        else if (providerKey === 'tencent') internalName = 'tencent';

                        if (config[internalName]) {
                            config[internalName].apiKey = providerConfig.api_key;
                            config[internalName].baseUrl = providerConfig.base || config[internalName].baseUrl;
                        }
                    }
                }
                console.log('成功加载JSON配置');
            }
        } catch (error) {
            console.error('JSON配置系统初始化失败:', error.message);
            // 返回默认配置
        }

        return config;
    }

    
    /**
     * 生成配置页面HTML
     */
    generateConfigPageHTML() {
        // 读取现有配置
        const existingConfig = this.loadExistingConfig();
        return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vision Analyzer - LLM配置</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
            color: #333;
        }

        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            border-radius: 12px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            font-weight: 700;
        }

        .header p {
            font-size: 1.1rem;
            opacity: 0.9;
        }

        .content {
            padding: 40px;
        }

        .current-status {
            background: #e8f4fd;
            border: 1px solid #bee5eb;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 30px;
        }

        .current-status h3 {
            color: #0c5460;
            margin-bottom: 10px;
            font-size: 1.1rem;
        }

        .current-status p {
            color: #0c5460;
            margin: 5px 0;
        }

        .current-provider-model {
            font-weight: 600;
            color: #4facfe;
        }

        .provider-tabs {
            display: flex;
            gap: 10px;
            margin-bottom: 30px;
            border-bottom: 2px solid #e0e0e0;
        }

        .tab {
            padding: 12px 24px;
            background: none;
            border: none;
            cursor: pointer;
            font-size: 1rem;
            font-weight: 500;
            color: #666;
            transition: all 0.3s ease;
            border-bottom: 3px solid transparent;
        }

        .tab.active {
            color: #4facfe;
            border-bottom-color: #4facfe;
        }

        .tab:hover {
            color: #4facfe;
        }

        .tab-content {
            display: none;
        }

        .tab-content.active {
            display: block;
        }

        .form-group {
            margin-bottom: 25px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #444;
        }

        .form-group input, .form-group select {
            width: 100%;
            padding: 12px 16px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 1rem;
            transition: border-color 0.3s ease;
            background-color: white;
        }

        .model-select-container {
            position: relative;
        }

        .model-select-container select {
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
            padding-right: 40px;
        }

        .model-select-container::after {
            content: '▼';
            position: absolute;
            right: 16px;
            top: 50%;
            transform: translateY(-50%);
            pointer-events: none;
            color: #666;
            font-size: 12px;
        }

        .model-loading {
            font-style: italic;
            color: #666;
        }

        .password-input-container {
            position: relative;
            display: flex;
            align-items: center;
        }

        .password-input-container input {
            padding-right: 45px;
        }

        .password-toggle {
            position: absolute;
            right: 12px;
            cursor: pointer;
            user-select: none;
            color: #666;
            font-size: 18px;
            background: none;
            border: none;
            padding: 5px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: color 0.3s ease;
        }

        .password-toggle:hover {
            color: #4facfe;
        }

        .password-toggle:active {
            color: #2196F3;
        }

        .form-group input:focus, .form-group select:focus {
            outline: none;
            border-color: #4facfe;
        }

        .btn {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            border: none;
            padding: 14px 28px;
            border-radius: 8px;
            font-size: 1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-right: 10px;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(79, 172, 254, 0.3);
        }

        .btn-secondary {
            background: #e0e0e0;
            color: #666;
        }

        .btn-secondary:hover {
            background: #d0d0d0;
        }

        .provider-info {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
        }

        .provider-info h3 {
            color: #4facfe;
            margin-bottom: 10px;
        }

        .provider-info p {
            line-height: 1.6;
            color: #666;
        }

        .alert {
            padding: 15px 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            display: none;
        }

        .alert-success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }

        .alert-error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }

        .alert-info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }

        .loading {
            display: none;
            text-align: center;
            margin: 20px 0;
        }

        .spinner {
            border: 3px solid #f3f3f3;
            border-top: 3px solid #4facfe;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 10px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .footer {
            background: #f8f9fa;
            padding: 20px 40px;
            text-align: center;
            color: #666;
            border-top: 1px solid #e0e0e0;
        }

        .btn-group {
            margin-top: 30px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🎯 Vision Analyzer</h1>
            <p>配置您的LLM服务提供商以启用视觉分析功能</p>
            <p style="margin-top: 10px; font-size: 0.9rem;">
                <a href="/manage" style="color: white; text-decoration: underline;">🔧 进入管理界面</a>
            </p>
        </div>

        <div class="content">
            <div class="current-status">
                <h3>📍 当前配置状态</h3>
                <p>当前Provider: <span class="current-provider-model" id="currentProvider">加载中...</span></p>
                <p>当前Model: <span class="current-provider-model" id="currentModel">加载中...</span></p>
            </div>

            <div class="alert alert-info" id="infoAlert">
                <strong>提示：</strong>请至少配置一个有效的LLM服务提供商
            </div>

            <div class="alert alert-success" id="successAlert">
                <strong>成功！</strong>配置已保存
            </div>

            <div class="alert alert-error" id="errorAlert">
                <strong>错误：</strong><span id="errorMessage"></span>
            </div>

            <div class="provider-tabs">
                <button class="tab active" onclick="showTab('zai')">智谱AI (Zai)</button>
                <button class="tab" onclick="showTab('moonshot')">Moonshot</button>
                <button class="tab" onclick="showTab('tencent')">腾讯混元</button>
                <button class="tab" onclick="showTab('custom')">自定义</button>
            </div>

            <!-- Zai (智谱AI) -->
            <div id="zai" class="tab-content active">
                <div class="provider-info">
                    <h3>🧠 智谱AI (Zai)</h3>
                    <p><strong>注册地址：</strong><a href="https://open.bigmodel.cn/" target="_blank">https://open.bigmodel.cn/</a></p>
                    <p><strong>说明：</strong>智谱AI提供高质量的中文视觉理解能力，适合中文用户使用</p>
                </div>

                <form id="zaiForm">
                    <div class="form-group">
                        <label for="zaiApiKey">API密钥</label>
                        <div class="password-input-container">
                            <input type="password" id="zaiApiKey" placeholder="请输入您的智谱AI API密钥" value="${existingConfig.zai.apiKey}" required>
                            <button class="password-toggle" onmousedown="showPassword('zaiApiKey')" onmouseup="hidePassword('zaiApiKey')" onmouseleave="hidePassword('zaiApiKey')" ontouchstart="showPassword('zaiApiKey')" ontouchend="hidePassword('zaiApiKey')" title="按住显示密码">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                                    <circle cx="12" cy="12" r="3"></circle>
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="zaiModel">选择视觉模型</label>
                        <div class="model-select-container">
                            <select id="zaiModel" name="model">
                                <option value="">正在加载模型列表...</option>
                            </select>
                        </div>
                    </div>
                </form>
            </div>

            <!-- Moonshot -->
            <div id="moonshot" class="tab-content">
                <div class="provider-info">
                    <h3>🌙 Moonshot AI</h3>
                    <p><strong>注册地址：</strong><a href="https://platform.moonshot.cn/" target="_blank">https://platform.moonshot.cn/</a></p>
                    <p><strong>说明：</strong>月之暗面提供的多模态大模型，支持高分辨率图像理解</p>
                </div>

                <form id="moonshotForm">
                    <div class="form-group">
                        <label for="moonshotApiKey">API密钥</label>
                        <div class="password-input-container">
                            <input type="password" id="moonshotApiKey" placeholder="请输入您的Moonshot API密钥" value="${existingConfig.moonshot.apiKey}" required>
                            <button class="password-toggle" onmousedown="showPassword('moonshotApiKey')" onmouseup="hidePassword('moonshotApiKey')" onmouseleave="hidePassword('moonshotApiKey')" ontouchstart="showPassword('moonshotApiKey')" ontouchend="hidePassword('moonshotApiKey')" title="按住显示密码">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                                    <circle cx="12" cy="12" r="3"></circle>
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="moonshotModel">选择视觉模型</label>
                        <div class="model-select-container">
                            <select id="moonshotModel" name="model">
                                <option value="">正在加载模型列表...</option>
                            </select>
                        </div>
                    </div>
                </form>
            </div>

            <!-- Tencent -->
            <div id="tencent" class="tab-content">
                <div class="provider-info">
                    <h3>🏢 腾讯混元</h3>
                    <p><strong>注册地址：</strong><a href="https://console.cloud.tencent.com/hunyuan" target="_blank">https://console.cloud.tencent.com/hunyuan</a></p>
                    <p><strong>说明：</strong>腾讯提供的混元大模型，性能优异，支持多种视觉任务</p>
                </div>

                <form id="tencentForm">
                    <div class="form-group">
                        <label for="tencentApiKey">API密钥</label>
                        <div class="password-input-container">
                            <input type="password" id="tencentApiKey" placeholder="请输入您的腾讯混元 API密钥" value="${existingConfig.tencent.apiKey}" required>
                            <button class="password-toggle" onmousedown="showPassword('tencentApiKey')" onmouseup="hidePassword('tencentApiKey')" onmouseleave="hidePassword('tencentApiKey')" ontouchstart="showPassword('tencentApiKey')" ontouchend="hidePassword('tencentApiKey')" title="按住显示密码">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                                    <circle cx="12" cy="12" r="3"></circle>
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="tencentModel">选择视觉模型</label>
                        <div class="model-select-container">
                            <select id="tencentModel" name="model">
                                <option value="">正在加载模型列表...</option>
                            </select>
                        </div>
                    </div>
                </form>
            </div>

            <!-- Custom -->
            <div id="custom" class="tab-content">
                <div class="provider-info">
                    <h3>🔧 自定义服务商</h3>
                    <p><strong>说明：</strong>如果您有其他兼容OpenAI API格式的服务商，可以在这里配置</p>
                </div>

                <form id="customForm">
                    <div class="form-group">
                        <label for="customName">服务商名称</label>
                        <input type="text" id="customName" placeholder="例如: openai, claude" value="${existingConfig.custom.name}" required>
                    </div>

                    <div class="form-group">
                        <label for="customBaseUrl">API基础URL</label>
                        <input type="url" id="customBaseUrl" placeholder="https://api.openai.com/v1" value="${existingConfig.custom.baseUrl}" required>
                    </div>

                    <div class="form-group">
                        <label for="customApiKey">API密钥</label>
                        <div class="password-input-container">
                            <input type="password" id="customApiKey" placeholder="请输入您的API密钥" value="${existingConfig.custom.apiKey}" required>
                            <button class="password-toggle" onmousedown="showPassword('customApiKey')" onmouseup="hidePassword('customApiKey')" onmouseleave="hidePassword('customApiKey')" ontouchstart="showPassword('customApiKey')" ontouchend="hidePassword('customApiKey')" title="按住显示密码">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
                                    <circle cx="12" cy="12" r="3"></circle>
                                </svg>
                            </button>
                        </div>
                    </div>
                </form>
            </div>

            <div class="loading" id="loading">
                <div class="spinner"></div>
                <p>正在验证API密钥...</p>
            </div>

            <div class="btn-group">
                <button class="btn" onclick="validateAndSaveCurrentProvider()">验证并保存</button>
                <button class="btn btn-secondary" onclick="skipConfiguration()">跳过配置</button>
            </div>
        </div>

        <div class="footer">
            <p>配置完成后，您可以重新启动Vision Analyzer来使用完整的视觉分析功能</p>
        </div>
    </div>

    <script>
        let currentTab = 'zai';

        // 显示密码
        function showPassword(inputId) {
            const input = document.getElementById(inputId);
            if (input) {
                input.type = 'text';
            }
        }

        // 隐藏密码
        function hidePassword(inputId) {
            const input = document.getElementById(inputId);
            if (input) {
                input.type = 'password';
            }
        }

        function showTab(tabName) {
            // 隐藏所有tab内容
            const contents = document.querySelectorAll('.tab-content');
            contents.forEach(content => content.classList.remove('active'));

            // 移除所有tab的active类
            const tabs = document.querySelectorAll('.tab');
            tabs.forEach(tab => tab.classList.remove('active'));

            // 显示选中的tab
            document.getElementById(tabName).classList.add('active');
            event.target.classList.add('active');

            currentTab = tabName;

            // 隐藏所有提示信息
            hideAllAlerts();
        }

        function hideAllAlerts() {
            document.getElementById('infoAlert').style.display = 'none';
            document.getElementById('successAlert').style.display = 'none';
            document.getElementById('errorAlert').style.display = 'none';
        }

        function showAlert(type, message) {
            hideAllAlerts();
            const alert = document.getElementById(type + 'Alert');
            if (type === 'error' && message) {
                document.getElementById('errorMessage').textContent = message;
            }
            alert.style.display = 'block';
        }

        function showLoading(show) {
            document.getElementById('loading').style.display = show ? 'block' : 'none';
        }

        function getCurrentProviderData() {
            let data = {};

            switch (currentTab) {
                case 'zai':
                    data = {
                        name: 'zai',
                        baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
                        apiKey: document.getElementById('zaiApiKey').value.trim()
                    };
                    break;
                case 'moonshot':
                    data = {
                        name: 'moonshot',
                        baseUrl: 'https://api.moonshot.cn/v1',
                        apiKey: document.getElementById('moonshotApiKey').value.trim()
                    };
                    break;
                case 'tencent':
                    data = {
                        name: 'tencent',
                        baseUrl: 'https://api.hunyuan.cloud.tencent.com/v1',
                        apiKey: document.getElementById('tencentApiKey').value.trim()
                    };
                    break;
                case 'custom':
                    data = {
                        name: document.getElementById('customName').value.trim(),
                        baseUrl: document.getElementById('customBaseUrl').value.trim(),
                        apiKey: document.getElementById('customApiKey').value.trim()
                    };
                    break;
            }

            return data;
        }

        async function validateAndSaveCurrentProvider() {
            const data = getCurrentProviderData();

            if (!data.apiKey) {
                showAlert('error', '请输入API密钥');
                return;
            }

            // 检查API密钥是否为占位符或示例文本
            const placeholderPatterns = [
                /your-.*-api-key-here/i,
                /你的.*api密钥/i,
                /sk-your-real-.*-key-here/i,
                /sk-test-demo-key/i,
                /test-api-key-demo/i,
                /your-real-.*-key-here/i,
                /demo/i,
                /example/i,
                /placeholder/i,
                /占位符/i,
                /请输入/i
            ];

            const isPlaceholder = placeholderPatterns.some(pattern => pattern.test(data.apiKey));
            if (isPlaceholder) {
                showAlert('error', '请输入真实的API密钥，不能使用占位符或示例文本');
                return;
            }

            if (currentTab === 'custom' && (!data.name || !data.baseUrl)) {
                showAlert('error', '请填写完整的服务商信息');
                return;
            }

            showLoading(true);
            hideAllAlerts();

            try {
                const response = await fetch('/validate-provider', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(data)
                });

                const result = await response.json();

                if (result.success) {
                    // 验证成功，保存配置
                    const saveResponse = await fetch('/save-config', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({
                            ...data,
                            models: result.models || []
                        })
                    });

                    const saveResult = await saveResponse.json();

                    if (saveResult.success) {
                        showAlert('success', '配置保存成功！');
                        // 更新当前配置显示
                        loadCurrentStatus();
                        setTimeout(() => {
                            window.close();
                        }, 2000);
                    } else {
                        showAlert('error', '保存配置失败: ' + saveResult.error);
                    }
                } else {
                    showAlert('error', 'API密钥验证失败: ' + result.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        function skipConfiguration() {
            if (confirm('跳过配置将无法使用视觉分析功能，确定要跳过吗？')) {
                window.close();
            }
        }

        // Provider模型映射
        const providerModels = {
            'zai': [
                { id: 'glm-4.5v', name: 'GLM-4.5 Vision' },
                { id: 'glm-4-flash', name: 'GLM-4 Flash Vision' },
                { id: 'glm-4-plus', name: 'GLM-4 Plus Vision' },
                { id: 'glm-4-long', name: 'GLM-4 Long Vision' }
            ],
            'moonshot': [
                { id: 'moonshot-v1-8k-vision-preview', name: 'Moonshot Vision 8K' },
                { id: 'moonshot-v1-32k-vision-preview', name: 'Moonshot Vision 32K' },
                { id: 'moonshot-v1-128k-vision-preview', name: 'Moonshot Vision 128K' }
            ],
            'tencent': [
                { id: 'hunyuan-vision', name: 'Hunyuan Vision' },
                { id: 'hunyuan-turbo-vision', name: 'Hunyuan Turbo Vision' },
                { id: 'hunyuan-t1-vision', name: 'Hunyuan T1 Vision' },
                { id: 'hunyuan-large-vision', name: 'Hunyuan Large Vision' }
            ]
        };

        // 加载当前配置状态
        async function loadCurrentStatus() {
            try {
                const response = await fetch('/list-providers');
                const data = await response.json();

                if (data.success) {
                    // 尝试获取当前provider和model
                    try {
                        const configResponse = await fetch('/get-current-config');
                        const configData = await configResponse.json();

                        if (configData.success) {
                            const currentProvider = configData.current_provider || 'unknown';
                            const currentModel = configData.current_provider_model || 'unknown';

                            document.getElementById('currentProvider').textContent = currentProvider;
                            document.getElementById('currentModel').textContent = currentModel;
                        } else {
                            document.getElementById('currentProvider').textContent = '未配置';
                            document.getElementById('currentModel').textContent = '未配置';
                        }
                    } catch (error) {
                        console.error('加载当前配置失败:', error);
                        document.getElementById('currentProvider').textContent = '加载失败';
                        document.getElementById('currentModel').textContent = '加载失败';
                    }
                }
            } catch (error) {
                console.error('加载状态失败:', error);
                document.getElementById('currentProvider').textContent = '未知';
                document.getElementById('currentModel').textContent = '未知';
            }
        }

        // 加载provider的模型列表
        function loadProviderModels(providerName) {
            const selectElement = document.getElementById(providerName + 'Model');
            const models = providerModels[providerName] || [];

            // 清空现有选项
            selectElement.innerHTML = '';

            // 添加模型选项
            models.forEach(model => {
                const option = document.createElement('option');
                option.value = model.id;
                option.textContent = model.name;
                selectElement.appendChild(option);
            });

            // 如果没有模型，显示占位符
            if (models.length === 0) {
                const option = document.createElement('option');
                option.value = '';
                option.textContent = '暂无可用模型';
                option.disabled = true;
                selectElement.appendChild(option);
            }
        }

        // 切换tab时加载模型
        function showTab(tabName) {
            // 隐藏所有tab内容
            const contents = document.querySelectorAll('.tab-content');
            contents.forEach(content => content.classList.remove('active'));

            // 移除所有tab的active类
            const tabs = document.querySelectorAll('.tab');
            tabs.forEach(tab => tab.classList.remove('active'));

            // 显示选中的tab
            document.getElementById(tabName).classList.add('active');
            event.target.classList.add('active');

            currentTab = tabName;

            // 隐藏所有提示信息
            hideAllAlerts();

            // 加载该provider的模型列表
            if (providerModels[tabName]) {
                loadProviderModels(tabName);
            }
        }

        // 修改getCurrentProviderData函数以包含模型信息
        function getCurrentProviderData() {
            let data = {};

            switch (currentTab) {
                case 'zai':
                    data = {
                        name: 'zai',
                        baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
                        apiKey: document.getElementById('zaiApiKey').value.trim(),
                        model: document.getElementById('zaiModel').value
                    };
                    break;
                case 'moonshot':
                    data = {
                        name: 'moonshot',
                        baseUrl: 'https://api.moonshot.cn/v1',
                        apiKey: document.getElementById('moonshotApiKey').value.trim(),
                        model: document.getElementById('moonshotModel').value
                    };
                    break;
                case 'tencent':
                    data = {
                        name: 'tencent',
                        baseUrl: 'https://api.hunyuan.cloud.tencent.com/v1',
                        apiKey: document.getElementById('tencentApiKey').value.trim(),
                        model: document.getElementById('tencentModel').value
                    };
                    break;
                case 'custom':
                    data = {
                        name: document.getElementById('customName').value.trim(),
                        baseUrl: document.getElementById('customBaseUrl').value.trim(),
                        apiKey: document.getElementById('customApiKey').value.trim(),
                        model: 'custom-model' // 自定义provider使用默认模型
                    };
                    break;
            }

            return data;
        }

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            showAlert('info');

            // 加载当前状态
            loadCurrentStatus();

            // 加载默认tab(zai)的模型列表
            loadProviderModels('zai');
        });
    </script>
</body>
</html>`;
    }

    /**
     * 处理服务商验证请求
     */
    async handleProviderValidation(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const data = JSON.parse(body);
                const result = await this.validateProvider(data);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 验证服务商API密钥
     */
    async validateProvider(data) {
        try {
            // 尝试获取模型列表来验证API密钥
            const models = await this.fetchProviderModels(data.baseUrl, data.apiKey);

            if (models && models.length > 0) {
                return {
                    success: true,
                    models: models,
                    message: 'API密钥验证成功'
                };
            } else {
                return {
                    success: false,
                    error: '无法获取模型列表'
                };
            }
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }

    /**
     * 获取服务商的模型列表
     */
    async fetchProviderModels(baseUrl, apiKey) {
        return new Promise((resolve, reject) => {
            const url = `${baseUrl}/models`;
            const options = {
                headers: {
                    'Authorization': `Bearer ${apiKey}`,
                    'Content-Type': 'application/json'
                }
            };

            const client = url.startsWith('https://') ? https : http;
            const req = client.request(url, options, (res) => {
                let body = '';
                res.on('data', chunk => body += chunk);
                res.on('end', () => {
                    try {
                        if (res.statusCode === 200) {
                            const data = JSON.parse(body);
                            // 过滤出支持视觉的模型
                            const visionModels = data.data?.filter(model =>
                                model.id && (
                                    model.id.includes('vision') ||
                                    model.id.includes('image') ||
                                    model.id.includes('multimodal') ||
                                    model.id.includes('4v') // 智谱的4v模型
                                )
                            ) || [];
                            resolve(visionModels.length > 0 ? visionModels : data.data || []);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${body}`));
                        }
                    } catch (e) {
                        reject(e);
                    }
                });
            });

            req.on('error', reject);
            req.end();
        });
    }

    /**
     * 处理保存配置请求
     */
    async handleSaveConfig(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const data = JSON.parse(body);
                const result = await this.saveConfig(data);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 保存配置到JSON文件
     */
    async saveConfig(data) {
        try {
            // 使用JSON配置管理器
            const JsonConfigManager = require('./lib/config/json-config-manager');
            const configManager = new JsonConfigManager(this.projectRoot);

            let config;
            try {
                config = configManager.getConfig() || {};
            } catch (error) {
                // 如果无法读取现有配置，创建新配置
                config = {
                    version: '1.0.0',
                    providers: {}
                };
            }

            // 确保providers对象存在
            if (!config.providers) {
                config.providers = {};
            }

            // 更新或添加provider配置
            if (!config.providers[data.name]) {
                config.providers[data.name] = {
                    base: data.baseUrl,
                    api_key: data.apiKey,
                    models: []
                };
            }

            // 更新provider基本信息
            config.providers[data.name].base = data.baseUrl;
            config.providers[data.name].api_key = data.apiKey;

            // 确保models数组存在
            if (!config.providers[data.name].models) {
                config.providers[data.name].models = [];
            }

            // 将选择的模型添加到provider的models列表中（如果不存在）
            let newCurrentProviderModel = '';
            if (data.model && data.model !== 'custom-model') {
                const modelId = data.model;

                // 检查模型是否已存在
                const existingModelIndex = config.providers[data.name].models.findIndex(m => {
                    if (typeof m === 'string') {
                        return m === modelId;
                    } else if (m && typeof m === 'object') {
                        return (m.name === modelId) || (m.id === modelId);
                    }
                    return false;
                });

                if (existingModelIndex === -1) {
                    // 直接添加字符串模型
                    config.providers[data.name].models.push(modelId);
                }

                // 更新当前provider模型
                newCurrentProviderModel = `${data.name}-${modelId}`;
            } else {
                // 自定义provider的情况
                newCurrentProviderModel = data.name;
            }

            // 更新配置
            config.current_provider_model = newCurrentProviderModel;

            // 保存配置
            configManager.saveConfig(config);

            return {
                success: true,
                message: '配置保存成功',
                // 返回最新的配置信息，用于同步更新页面显示
                currentProvider: data.name,
                currentModel: newCurrentProviderModel
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }

    /**
     * 处理切换服务商
     */
    async handleSwitchProvider(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const { provider } = JSON.parse(body);
                const result = await this.switchProvider(provider);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 处理删除服务商
     */
    async handleDeleteProvider(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const { provider } = JSON.parse(body);
                const result = await this.removeProvider(provider);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 处理列出服务商
     */
    async handleListProviders(req, res) {
        try {
            const providers = await this.listProviders();

            res.setHeader('Content-Type', 'application/json');
            res.writeHead(200);
            res.end(JSON.stringify(providers));
        } catch (error) {
            res.setHeader('Content-Type', 'application/json');
            res.writeHead(500);
            res.end(JSON.stringify({ success: false, error: error.message }));
        }
    }

    /**
     * 处理添加模型
     */
    async handleAddModel(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const { provider, modelId } = JSON.parse(body);
                const result = await this.addModel(provider, modelId);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 处理删除模型
     */
    async handleDeleteModel(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const { provider, modelId } = JSON.parse(body);
                const result = await this.deleteModel(provider, modelId);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 处理列出模型
     */
    async handleListModels(req, res) {
        try {
            const url = new URL(req.url, `http://127.0.0.1:${this.port}`);
            const provider = url.searchParams.get('provider');
            const models = await this.listProviderModels(provider);

            res.setHeader('Content-Type', 'application/json');
            res.writeHead(200);
            res.end(JSON.stringify(models));
        } catch (error) {
            res.setHeader('Content-Type', 'application/json');
            res.writeHead(500);
            res.end(JSON.stringify({ success: false, error: error.message }));
        }
    }

    /**
     * 处理切换模型
     */
    async handleSwitchModel(req, res) {
        let body = '';
        req.on('data', chunk => body += chunk);
        req.on('end', async () => {
            try {
                const { provider, model } = JSON.parse(body);
                const result = await this.switchModel(provider, model);

                res.setHeader('Content-Type', 'application/json');
                res.writeHead(200);
                res.end(JSON.stringify(result));
            } catch (error) {
                res.setHeader('Content-Type', 'application/json');
                res.writeHead(400);
                res.end(JSON.stringify({ success: false, error: error.message }));
            }
        });
    }

    /**
     * 切换当前使用的服务商
     */
    async switchProvider(providerName) {
        try {
            const envPath = path.join(this.projectRoot, '.env');
            if (!fs.existsSync(envPath)) {
                return { success: false, error: '配置文件不存在' };
            }

            let envContent = fs.readFileSync(envPath, 'utf8');
            const currentModelRegex = /current_provider_model=[^\n\r]*/;

            if (currentModelRegex.test(envContent)) {
                envContent = envContent.replace(currentModelRegex, `current_provider_model=${providerName}`);
            } else {
                envContent = `current_provider_model=${providerName}\n${envContent}`;
            }

            fs.writeFileSync(envPath, envContent);

            return { success: true, message: `已切换到 ${providerName}` };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 删除服务商配置
     */
    async removeProvider(providerName) {
        try {
            const envPath = path.join(this.projectRoot, '.env');
            if (!fs.existsSync(envPath)) {
                return { success: false, error: '配置文件不存在' };
            }

            let envContent = fs.readFileSync(envPath, 'utf8');

            // 注释掉服务商配置
            const providerRegex = new RegExp(`^${providerName}=.*$`, 'gm');
            envContent = envContent.replace(providerRegex, `# ${providerName}=REMOVED`);

            // 从providers列表中移除
            const providersRegex = /providers=\[[^\]]*\]/;
            const currentProvidersMatch = envContent.match(providersRegex);

            if (currentProvidersMatch) {
                try {
                    const currentProviders = JSON.parse(currentProvidersMatch[0].split('=')[1]);
                    const updatedProviders = currentProviders.filter(p => p !== providerName);
                    const newProvidersLine = `providers=${JSON.stringify(updatedProviders)}`;
                    envContent = envContent.replace(providersRegex, newProvidersLine);
                } catch (error) {
                    // 忽略解析错误
                }
            }

            fs.writeFileSync(envPath, envContent);

            return { success: true, message: `已删除 ${providerName} 配置` };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 列出所有服务商
     */
    async listProviders() {
        try {
            const existingConfig = this.loadExistingConfig();
            const providers = [];

            for (const [name, config] of Object.entries(existingConfig)) {
                if (name === 'currentProviderModel' || name === 'providers') continue;

                if (config.apiKey && config.apiKey.trim()) {
                    providers.push({
                        name,
                        baseUrl: config.baseUrl,
                        hasApiKey: true,
                        apiKey: config.apiKey.slice(-4) ? `***${config.apiKey.slice(-4)}` : '***'
                    });
                }
            }

            return { success: true, providers };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 列出提供商的可用模型
     */
    async listProviderModels(providerName) {
        try {
            const existingConfig = this.loadExistingConfig();
            const providerConfig = existingConfig[providerName];

            if (!providerConfig || !providerConfig.apiKey) {
                return { success: false, error: '提供商未配置或缺少API密钥' };
            }

            // 返回基本模型信息（基于已知配置）
            let models = [];

            if (providerName === 'moonshot') {
                models = [
                    { id: 'moonshot-v1-8k-vision-preview', name: 'Moonshot Vision 8K', type: 'vision' },
                    { id: 'moonshot-v1-32k-vision-preview', name: 'Moonshot Vision 32K', type: 'vision' },
                    { id: 'moonshot-v1-128k-vision-preview', name: 'Moonshot Vision 128K', type: 'vision' }
                ];
            } else if (providerName === 'tencent') {
                models = [
                    { id: 'tencent-hunyuan-vision', name: 'Hunyuan Vision', type: 'vision' }
                ];
            } else if (providerName === 'zai') {
                models = [
                    { id: 'glm-4.5v', name: 'GLM-4.5 Vision', type: 'vision' }
                ];
            }

            return { success: true, models };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 添加模型到服务商
     */
    async addModel(providerName, modelId) {
        try {
            const envPath = path.join(this.projectRoot, '.env');
            if (!fs.existsSync(envPath)) {
                return { success: false, error: '配置文件不存在' };
            }

            let envContent = fs.readFileSync(envPath, 'utf8');
            const providerRegex = new RegExp(`^${providerName}=(.*)$`, 'gm');
            const match = providerRegex.exec(envContent);

            if (!match) {
                return { success: false, error: `服务商 ${providerName} 不存在` };
            }

            try {
                const config = JSON.parse(match[1]);
                if (!config.models) {
                    config.models = [];
                }

                if (!config.models.includes(modelId)) {
                    config.models.push(modelId);

                    const newConfigLine = `${providerName}=${JSON.stringify(config)}`;
                    envContent = envContent.replace(providerRegex, newConfigLine);

                    fs.writeFileSync(envPath, envContent);
                    return { success: true, message: `已添加模型 ${modelId} 到 ${providerName}` };
                } else {
                    return { success: false, error: `模型 ${modelId} 已存在` };
                }
            } catch (error) {
                return { success: false, error: '解析配置失败' };
            }
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 从服务商删除模型
     */
    async deleteModel(providerName, modelId) {
        try {
            const envPath = path.join(this.projectRoot, '.env');
            if (!fs.existsSync(envPath)) {
                return { success: false, error: '配置文件不存在' };
            }

            let envContent = fs.readFileSync(envPath, 'utf8');
            const providerRegex = new RegExp(`^${providerName}=(.*)$`, 'gm');
            const match = providerRegex.exec(envContent);

            if (!match) {
                return { success: false, error: `服务商 ${providerName} 不存在` };
            }

            try {
                const config = JSON.parse(match[1]);
                if (!config.models || !Array.isArray(config.models)) {
                    return { success: false, error: '模型配置不存在' };
                }

                const index = config.models.indexOf(modelId);
                if (index > -1) {
                    config.models.splice(index, 1);

                    const newConfigLine = `${providerName}=${JSON.stringify(config)}`;
                    envContent = envContent.replace(providerRegex, newConfigLine);

                    fs.writeFileSync(envPath, envContent);
                    return { success: true, message: `已从 ${providerName} 删除模型 ${modelId}` };
                } else {
                    return { success: false, error: `模型 ${modelId} 不存在` };
                }
            } catch (error) {
                return { success: false, error: '解析配置失败' };
            }
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 列出服务商的模型
     */
    async listModels(providerName) {
        try {
            const config = this.loadExistingConfig();
            const providerConfig = config[providerName];

            if (!providerConfig) {
                return { success: false, error: `服务商 ${providerName} 不存在` };
            }

            // 尝试获取实际模型列表
            try {
                const models = await this.fetchProviderModels(providerConfig.baseUrl, providerConfig.apiKey);
                return { success: true, models: models || [] };
            } catch (error) {
                // 如果API调用失败，返回配置中的模型列表
                return { success: true, models: [], error: '无法获取实时模型列表' };
            }
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 切换模型
     */
    async switchModel(providerName, modelId) {
        try {
            // 首先尝试使用JSON配置管理器
            try {
                const JsonConfigManager = require('./lib/config/json-config-manager');
                const configManager = new JsonConfigManager(this.projectRoot);

                const config = configManager.getConfig();
                if (!config) {
                    return { success: false, error: '无法读取配置文件' };
                }

                // 更新当前提供商模型（只保存模型ID，不带提供商前缀）
                config.current_provider_model = modelId;

                // 保存配置
                configManager.saveConfig(config);

                return { success: true, message: `已切换到 ${providerName}-${modelId}` };
            } catch (jsonError) {
                console.log('JSON配置保存失败，尝试使用.env格式:', jsonError.message);
                // 回退到.env文件格式
                return this.switchModelViaEnv(providerName, modelId);
            }
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

    /**
     * 获取模型显示名称
     * @param {string} providerName - Provider名称
     * @param {string} modelId - 模型ID
     * @returns {string} 模型显示名称
     */
    getModelDisplayName(providerName, modelId) {
        const modelNames = {
            'zai': {
                'glm-4.5v': 'GLM-4.5 Vision'
            },
            'moonshot': {
                'moonshot-v1-8k-vision-preview': 'Moonshot Vision 8K',
                'moonshot-v1-32k-vision-preview': 'Moonshot Vision 32K',
                'moonshot-v1-128k-vision-preview': 'Moonshot Vision 128K'
            },
            'tencent': {
                'hunyuan-vision': 'Hunyuan Vision',
                'hunyuan-turbo-vision': 'Hunyuan Turbo Vision',
                'hunyuan-t1-vision': 'Hunyuan T1 Vision',
                'hunyuan-large-vision': 'Hunyuan Large Vision'
            }
        };

        return modelNames[providerName]?.[modelId] || modelId;
    }

    /**
     * 通过.env文件切换模型（回退方案）
     */
    async switchModelViaEnv(providerName, modelId) {
        try {
            const envPath = path.join(this.projectRoot, '.env');
            if (!fs.existsSync(envPath)) {
                return { success: false, error: '配置文件不存在' };
            }

            let envContent = fs.readFileSync(envPath, 'utf8');
            const currentModelRegex = /current_provider_model=[^\n\r]*/;
            const newModelConfig = `${providerName}-${modelId}`;

            if (currentModelRegex.test(envContent)) {
                envContent = envContent.replace(currentModelRegex, `current_provider_model=${newModelConfig}`);
            } else {
                envContent = `current_provider_model=${newModelConfig}\n${envContent}`;
            }

            fs.writeFileSync(envPath, envContent);

            return { success: true, message: `已切换到 ${newModelConfig}` };
        } catch (error) {
            return { success: false, error: error.message };
        }
    }

  /**
     * 生成管理页面HTML
     */
    generateManagePageHTML() {
        return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vision Analyzer - 管理界面</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
            color: #333;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 12px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            padding: 30px;
            text-align: center;
            position: relative;
        }

        .header h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
            font-weight: 700;
        }

        .header p {
            font-size: 1.1rem;
            opacity: 0.9;
        }

        .nav-tabs {
            display: flex;
            background: #f8f9fa;
            border-bottom: 2px solid #e0e0e0;
        }

        .nav-tab {
            flex: 1;
            padding: 15px 20px;
            text-align: center;
            cursor: pointer;
            border: none;
            background: none;
            font-size: 1rem;
            font-weight: 500;
            color: #666;
            transition: all 0.3s ease;
            border-bottom: 3px solid transparent;
        }

        .nav-tab.active {
            color: #4facfe;
            border-bottom-color: #4facfe;
            background: white;
        }

        .nav-tab:hover {
            color: #4facfe;
        }

        .content {
            padding: 40px;
        }

        .tab-content {
            display: none;
        }

        .tab-content.active {
            display: block;
        }

        .provider-card {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 20px;
            border: 2px solid transparent;
            transition: border-color 0.3s ease;
        }

        .provider-card.active {
            border-color: #4facfe;
        }

        .provider-card h3 {
            color: #4facfe;
            margin-bottom: 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .provider-actions {
            display: flex;
            gap: 10px;
        }

        .btn {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 6px;
            font-size: 0.9rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 5px 15px rgba(79, 172, 254, 0.3);
        }

        .btn-danger {
            background: linear-gradient(135deg, #ff6b6b 0%, #ff5252 100%);
        }

        .btn-secondary {
            background: #6c757d;
        }

        .btn-small {
            padding: 6px 12px;
            font-size: 0.8rem;
        }

        .model-list {
            margin-top: 15px;
            max-height: 200px;
            overflow-y: auto;
        }

        .model-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 12px;
            background: white;
            border-radius: 4px;
            margin-bottom: 5px;
            border: 1px solid #e0e0e0;
        }

        .model-item:hover {
            border-color: #4facfe;
        }

        .add-model-form {
            display: flex;
            gap: 10px;
            margin-top: 15px;
        }

        .add-model-form input {
            flex: 1;
            padding: 8px 12px;
            border: 2px solid #e0e0e0;
            border-radius: 4px;
            font-size: 0.9rem;
        }

        .add-model-form input:focus {
            outline: none;
            border-color: #4facfe;
        }

        .alert {
            padding: 15px 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            display: none;
        }

        .alert-success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }

        .alert-error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }

        .alert-info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }

        .loading {
            display: none;
            text-align: center;
            margin: 20px 0;
        }

        .spinner {
            border: 3px solid #f3f3f3;
            border-top: 3px solid #4facfe;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 10px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .status-indicator {
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            margin-right: 8px;
        }

        .status-active {
            background: #28a745;
        }

        .status-inactive {
            background: #6c757d;
        }

        .back-link {
            position: absolute;
            top: 20px;
            left: 20px;
            color: white;
            text-decoration: none;
            font-size: 1rem;
            opacity: 0.9;
            transition: opacity 0.3s ease;
        }

        .back-link:hover {
            opacity: 1;
        }

        .current-status {
            background: #e3f2fd;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
            border-left: 4px solid #4facfe;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <a href="/" class="back-link">← 返回配置</a>
            <h1>🔧 Vision Analyzer 管理界面</h1>
            <p>管理您的LLM服务商和模型配置</p>
        </div>

        <div class="nav-tabs">
            <button class="nav-tab active" onclick="showTab('providers')">服务商管理</button>
            <button class="nav-tab" onclick="showTab('models')">模型管理</button>
        </div>

        <div class="content">
            <div class="alert alert-info" id="infoAlert">
                <strong>提示：</strong>您可以在这里管理服务商和模型配置
            </div>

            <div class="alert alert-success" id="successAlert">
                <strong>成功！</strong>操作已完成
            </div>

            <div class="alert alert-error" id="errorAlert">
                <strong>错误：</strong><span id="errorMessage"></span>
            </div>

            <div class="loading" id="loading">
                <div class="spinner"></div>
                <p>正在处理请求...</p>
            </div>

            <!-- 服务商管理 -->
            <div id="providers" class="tab-content active">
                <div class="current-status" id="currentStatus">
                    <h4>当前状态</h4>
                    <p id="currentProviderText">加载中...</p>
                </div>

                <h3>已配置的服务商</h3>
                <div id="providersList"></div>
            </div>

            <!-- 模型管理 -->
            <div id="models" class="tab-content">
                <div id="modelManagement">
                    <h3>模型管理</h3>
                    <div id="modelsContent"></div>
                </div>
            </div>
        </div>
    </div>

    <script>
        let currentTab = 'providers';

        function showTab(tabName) {
            // 隐藏所有tab内容
            const contents = document.querySelectorAll('.tab-content');
            contents.forEach(content => content.classList.remove('active'));

            // 移除所有tab的active类
            const tabs = document.querySelectorAll('.nav-tab');
            tabs.forEach(tab => tab.classList.remove('active'));

            // 显示选中的tab
            document.getElementById(tabName).classList.add('active');
            event.target.classList.add('active');

            currentTab = tabName;

            // 隐藏所有提示信息
            hideAllAlerts();

            // 加载对应的数据
            if (tabName === 'providers') {
                loadProviders();
            } else if (tabName === 'models') {
                loadModelManagement();
            }
        }

        function hideAllAlerts() {
            document.getElementById('infoAlert').style.display = 'none';
            document.getElementById('successAlert').style.display = 'none';
            document.getElementById('errorAlert').style.display = 'none';
        }

        function showAlert(type, message) {
            hideAllAlerts();
            const alert = document.getElementById(type + 'Alert');
            if (type === 'error' && message) {
                document.getElementById('errorMessage').textContent = message;
            }
            alert.style.display = 'block';
        }

        function showLoading(show) {
            document.getElementById('loading').style.display = show ? 'block' : 'none';
        }

        async function loadProviders() {
            showLoading(true);
            try {
                const response = await fetch('/list-providers');
                const data = await response.json();

                if (data.success) {
                    renderProviders(data.providers);
                    await loadCurrentStatus();
                } else {
                    showAlert('error', data.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        async function loadCurrentStatus() {
            try {
                const response = await fetch('/list-providers');
                const data = await response.json();

                if (data.success) {
                    // 这里应该显示当前provider，但暂时显示基本信息
                    document.getElementById('currentProviderText').innerHTML =
                        '已配置 ' + data.providers.length + ' 个服务商';
                }
            } catch (error) {
                console.error('加载状态失败:', error);
            }
        }

        function renderProviders(providers) {
            const container = document.getElementById('providersList');

            if (providers.length === 0) {
                container.innerHTML = '<p>暂无配置的服务商，请先<a href="/">添加配置</a></p>';
                return;
            }

            container.innerHTML = providers.map(provider => \`
                <div class="provider-card">
                    <h3>
                        <span>
                            <span class="status-indicator status-active"></span>
                            \${provider.name}
                        </span>
                        <div class="provider-actions">
                            <button class="btn btn-small" onclick="switchProvider('\${provider.name}')">切换</button>
                            <button class="btn btn-danger btn-small" onclick="deleteProvider('\${provider.name}')">删除</button>
                        </div>
                    </h3>
                    <p><strong>API地址:</strong> \${provider.baseUrl}</p>
                    <p><strong>API密钥:</strong> \${provider.apiKey}</p>
                    <div class="model-list" id="models-\${provider.name}">
                        <button class="btn btn-small btn-secondary" onclick="loadProviderModels('\${provider.name}')">
                            加载模型列表
                        </button>
                    </div>
                </div>
            \`).join('');
        }

        async function loadProviderModels(providerName) {
            const container = document.getElementById(\`models-\${providerName}\`);
            container.innerHTML = '<p>加载中...</p>';

            try {
                const response = await fetch(\`/list-models?provider=\${providerName}\`);
                const data = await response.json();

                if (data.success) {
                    renderProviderModels(providerName, data.models);
                } else {
                    container.innerHTML = \`<p style="color: red;">加载失败: \${data.error}</p>\`;
                }
            } catch (error) {
                container.innerHTML = \`<p style="color: red;">网络错误: \${error.message}</p>\`;
            }
        }

        function renderProviderModels(providerName, models) {
            const container = document.getElementById(\`models-\${providerName}\`);

            if (models.length === 0) {
                container.innerHTML = '<p>暂无可用模型</p>';
                return;
            }

            container.innerHTML = \`
                <h4>可用模型</h4>
                <div class="model-list">
                    \${models.map(model => \`
                        <div class="model-item">
                            <span>\${model.id || model}</span>
                            <button class="btn btn-small btn-secondary" onclick="switchModel('\${providerName}', '\${model.id || model}')">使用</button>
                        </div>
                    \`).join('')}
                </div>
                <div class="add-model-form">
                    <input type="text" id="newModel-\${providerName}" placeholder="输入新模型ID">
                    <button class="btn btn-small" onclick="addModel('\${providerName}')">添加</button>
                </div>
            \`;
        }

        async function loadModelManagement() {
            const container = document.getElementById('modelsContent');
            container.innerHTML = '<p>请先在服务商管理中选择一个服务商查看模型</p>';
        }

        async function switchProvider(providerName) {
            if (!confirm(\`确定要切换到 \${providerName} 吗？\`)) return;

            showLoading(true);
            try {
                const response = await fetch('/switch-provider', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ provider: providerName })
                });

                const data = await response.json();
                if (data.success) {
                    showAlert('success', data.message);
                    await loadCurrentStatus();
                } else {
                    showAlert('error', data.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        async function deleteProvider(providerName) {
            if (!confirm(\`确定要删除 \${providerName} 吗？此操作不可撤销！\`)) return;

            showLoading(true);
            try {
                const response = await fetch('/delete-provider', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ provider: providerName })
                });

                const data = await response.json();
                if (data.success) {
                    showAlert('success', data.message);
                    await loadProviders();
                } else {
                    showAlert('error', data.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        async function switchModel(providerName, modelId) {
            if (!confirm(\`确定要切换到 \${providerName}-\${modelId} 吗？\`)) return;

            showLoading(true);
            try {
                const response = await fetch('/switch-model', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ provider: providerName, model: modelId })
                });

                const data = await response.json();
                if (data.success) {
                    showAlert('success', data.message);
                    await loadCurrentStatus();
                } else {
                    showAlert('error', data.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        async function addModel(providerName) {
            const input = document.getElementById(\`newModel-\${providerName}\`);
            const modelId = input.value.trim();

            if (!modelId) {
                showAlert('error', '请输入模型ID');
                return;
            }

            showLoading(true);
            try {
                const response = await fetch('/add-model', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ provider: providerName, modelId: modelId })
                });

                const data = await response.json();
                if (data.success) {
                    showAlert('success', data.message);
                    input.value = '';
                    await loadProviderModels(providerName);
                } else {
                    showAlert('error', data.error);
                }
            } catch (error) {
                showAlert('error', '网络错误: ' + error.message);
            } finally {
                showLoading(false);
            }
        }

        // 页面加载完成后加载服务商数据
        document.addEventListener('DOMContentLoaded', function() {
            loadProviders();
        });
    </script>
</body>
</html>`;
    }

    /**
     * 打开浏览器
     */
    openBrowser(url) {
        // 在测试环境中不执行真实的浏览器打开操作
        // 优先使用环境变量判断，允许测试通过删除环境变量来模拟非测试环境
        const isTestEnvironment = process.env.NODE_ENV === 'test' ||
                                process.env.JEST_WORKER_ID !== undefined;

        if (isTestEnvironment) {
            // 在测试环境中静默处理，避免"Cannot log after tests are done"警告
            return;
        }

        const platform = process.platform;
        let command;

        switch (platform) {
            case 'darwin':
                command = `open "${url}"`;
                break;
            case 'win32':
                command = `start "" "${url}"`;
                break;
            default:
                command = `xdg-open "${url}"`;
                break;
        }

        child_process.exec(command, (error) => {
            if (error) {
                console.log(`无法自动打开浏览器: ${error.message}`, `请手动访问: ${url}`);
            } else {
                console.log(`✅ 已在浏览器中打开配置页面`);
            }
        });
    }
}

module.exports = WebConfigServer;

// 如果直接运行此文件，则启动服务器
if (require.main === module) {
    const projectRoot = __dirname;
    const server = new WebConfigServer(projectRoot);

    server.start().then(() => {
        console.log('🎉 配置服务器启动成功！');
    }).catch(error => {
        console.error('❌ 配置服务器启动失败:', error.message);
        process.exit(1);
    });
}